OpenBlocks BX1とAWS IoTをつなげてAmazon S3にメッセージをなげてみる
こんにちは、せーのです。 AWS IoTが発表されてクラメソのブログでも色々と各機能の紹介をしています。触ってみた方は大体の感じがつかめてきたかと思います。 ここで実際のIoTデバイスからAWS IoTへ繋いで、データを送ってみたいと思います。使うデバイスはいつものBX1です。
ステップを確認する
Developers.IOをはじめ、大体のブログがAWS CLIを使ってコマンドラインで書かれているものが多いので、今回はマネージメントコンソールを使ってわかりやすくやってみましょう。 マネージメントコンソールで必要なステップは
1. Thingsを登録する 2. Rulesに必要なリソースとRulesを登録する 3. Certificateを登録する 4. Policyを登録する 5. CertificateにPolicyとThingsを紐付ける
この5つです。一方クライアント側となるデバイスで必要なことは
1. 証明書と鍵、ルートCA証明書を用意する 2. MQTTでpublishできるクライアントを用意する 3. (必要であれば)エンドポイントを確認する
この3つです。2の「MQTTでpublishできるクライアント」はいくつか種類があるのですが、AWS IoTとつなげることを考えると
- オープンソースの[Mosquito] - AWS IoT Device SDK
の2つが候補となるかと思います。Mosquitoの場合はエンドポイントの指定が必要ですが、AWS IoT Device SDKはそこらへんをいい感じにやってくれるので指定する必要はありません。 ということで今回はAWS IoT Device SDKを使ってみたいと思います。
やってみる
それではやってみましょう。まずはマネージメントコンソール側です。
Thingsを登録する
まずはThingsを登録します。[Create a resource]ボタンでCreate Panelを開き、[Create a Thing]ボタンを押します。
あとは名前を入れてCreateすればOKです。
Rulesに必要なリソースとRulesを登録する
つぎにRuleを登録していきます。今回は簡単にS3にメッセージを入れてみましょう。ということでS3のバケットを作成します。
AWS IoTに戻ってCreate Panelから[Create a Rule]ボタンを押します。
RuleはSQLライクにメッセージの処理方法を決めるコンポーネントです。今回は[bx1test]というtopicにメッセージが入ってきたらその全てのメッセージをS3に投げる、というRuleを作ります。 フィルタリングを決めたら次にアクションをつけていきます。
S3の場合は対象となるバケット名とIAM Roleを作ります。IoTRuleがS3を操作できるようにS3のPutObjectの権限をこのRuleにつけるわけです。
これでRuleの作成はOKです。Createしてみましょう。
Certificateを登録する
次はCertificate, 証明書を登録していきます。証明書は自分で作ったcsrを登録する方法と全てをAWSで作る方法の2つがあります。
今回は全てをAWSで作ってみます。これはなんとボタンを押すだけで出来てしまいます。Create Panelから[Create Certificate]ボタンを押し、[1-Click Certificate Create]ボタンを選択します。
これでPublic Key, Private Key, Certificateの3つがダウンロードできるリンクが表示されます。Certificateは後からでもダウンロードできますがPublic Key, Private Keyはこのワンチャンスを逃すとダウンロードできなくなるのでここで必ずダウンロードするようにして下さい。
Policyを登録する
さて、次はPolicyを登録します。これは後ほど証明書に紐付けるためのもので、このポリシーで設定した権限を、このPolicyを紐付ける証明書を使ってConnectしたデバイスが使える、ということです。 Create Panelから[Create a Policy]を選択します。今回はConnectとPublishが出来ればいいのですが、シンプルにiot系全てを全てのデバイスから動かせるPolicyを作成します。
CertificateにPolicyとThingsを紐付ける
最後は作成したCertificateにPolicyとThingsを紐付けます。作ったCertificateを選択して[Attach Policy][Attach Thing]をActionから選択します。
あとはそれぞれ表示された小窓からPolicy, Thingを登録すればOKです。
これでAWS側の設定はOKです。
デバイス(BX1)側の設定
ここからはBX1側の設定をしていきます。まずは各モジュールをインストールするためにnodeとnpmをインストールします。 /etc/apt/sources.listを開いて、コメントアウトされている行のコメントを外します。
vi /etc/apt/sources.list
deb http://ftp.plathome.co.jp/pub/debian wheezy main deb-src http://ftp.plathome.co.jp/pub/debian wheezy main deb http://ftp.plathome.co.jp/pub/debian-security wheezy/updates main deb-src http://ftp.plathome.co.jp/pub/debian-security wheezy/updates main #deb http://ftp.plathome.co.jp/pub/debian wheezy-backports main contrib non-free ←ここと #deb-src http://ftp.plathome.co.jp/pub/debian wheezy-backports main contrib non-- free ←ここのコメントを外す deb http://ftp.plathome.co.jp/pub/BX1/debian/wheezy ./
コメントを外したらnodeを入れていきます。元々のパッケージには入っていないのでholdします。
apt-get update apt-get install nodejs apt-get install nodejs-legasy echo nodejs hold | dpkg --set-selections echo nodejs-legacy hold | dpkg --set-selections
コメントを元にもどして再びパッケージをupdateし、npmを入れていきます。
apt-get update curl -L https://npmjs.org/install.sh | sh
nodeとnpmが入っているかどうかバージョンで確認します。
node -v npm -v
次にAWS IoT Device SDKをインストールします。インストールができたらAWS IoT Device SDKに必要なモジュールをnpmでインストールします。
apt-get install git git clone https://github.com/aws/aws-iot-device-sdk-js.git cd aws-iot-device-sdk-js/ npm install mqtt npm install blessed npm blessed-contrib npm install minimist
デバイスのデフォルトとなるファイル名をヘルプコマンドで確認します。
nodejs examples/device-example.js -h Usage: device-example.js [OPTION...] device-example.js: connect to the AWS IoT service and publish/subscribe to topics using MQTT, test modes 1-2 Options -g, --aws-region=REGION AWS IoT region -i, --client-id=ID use ID as client ID -k, --private-key=FILE use FILE as private key -c, --client-certificate=FILE use FILE as client certificate -a, --ca-certificate=FILE use FILE as CA certificate -f, --certificate-dir=DIR look in DIR for certificates -F, --configuration-file=FILE use FILE (JSON format) for configuration -r, --reconnect-period-ms=VALUE use VALUE as the reconnect period (ms) -t, --test-mode=[1-n] set test mode for multi-process tests -T, --thing-name=THINGNAME access thing shadow named THINGNAME -d, --delay-ms=VALUE delay in milliseconds before publishing Default values aws-region us-east-1 client-id $USER<random-integer> private-key private.pem.key client-certificate certificate.pem.crt ca-certificate root-CA.crt reconnect-period-ms 3000ms delay-ms 4000ms test-mode 1
マネージメントコンソールからダウンロードしたCertificateのうちCertificate, Private Keyの証明書をそれぞれ[certificate.pem.crt][private.pem.key]に変更し、macならCyberduck, WindowsならWinSCPなどを使ってまっさらなフォルダに転送します。今回はルートフォルダ直下に[certs]というフォルダを作りました。
cd ~ mkdir certs
ここにroot CA証明書を入れます。なおcurlコマンドはBX1には初期では入っていないためインストールします。
apt-get install curl cd ~/certs/ curl -o root-CA.pem https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem
それぞれのアクセス権限をルートCA証明書: 644, 鍵,証明書: 600で設定し、入っている内容を確認します。
chmod 644 ~/certs/root-CA.crt chmod 600 ~/certs/certificate.pem.crt chmod 600 ~/certs/private.pem.key ls -la ~/certs/ total 20 drwxr-xr-x 2 root root 4096 Nov 1 23:47 . drwxr-xr-x 10 root root 4096 Nov 1 18:19 .. -rw-r----- 1 root root 1220 Nov 2 02:02 certificate.pem.crt -rw-r----- 1 root root 1679 Nov 2 02:02 private.pem.key -rw-r--r-- 1 root root 1758 Nov 2 02:02 root-CA.crt
BX1はiptablesで必要以外のポートが閉じられているため、AWS IoTで必要な8883ポートを空けます。
/sbin/iptables -A INPUT -p tcp --dport 8883 -j ACCEPT /sbin/iptables -A INPUT -p tcp --sport 8883 -j ACCEPT
さあ、これで準備は完了です。exampleからMQTTSでメッセージを送るとRulesにてそのメッセージをSubscribeしてS3に送られます。 ただ、exampleは[topic_1][topic_2]となっているので、ここを[bx1test]に変更します。今回はtestModeという変数を1にて送るのでtestMode===1のところだけでOKです。
vi examples/device-example.js
... device .on('connect', function() { const minimumDelay=250; console.log('connect'); if (args.testMode === 1) { device.subscribe('bx1test'); } ... timeout = setInterval( function() { count++; if (args.testMode === 1) { device.publish('bx1test', JSON.stringify({ mode_1_process: count })); } else ......
コードを読んで頂ければわかるように最初にtopicをsubscribeしてその後にsetIntervalで定期的にtopicに向けてカウントアップした数値をpublishしているだけです。 それでは実際に実行してみましょう。exampleのRegionはus-west-1なので東京リージョンであるap-northeast-1を指定します。
nodejs examples/device-example.js -f ~/certs/ -g ap-northeast-1 connect message bx1test {"mode_1_process":1} message bx1test {"mode_1_process":2} message bx1test {"mode_1_process":3} message bx1test {"mode_1_process":4} message bx1test {"mode_1_process":5}
publishは成功です!ではsubscribeはどうでしょうか。S3のバケットの中身を見てみます。
入ってますね!中身を見ると
{"mode_1_process":5}
publishされたjsonがそのまま入っていますね。うまく行きました。
まとめ
いかがでしたでしょうか。今回ご紹介したようにAWS側は非常にシンプルです。後はデバイス側の実装だけですが、それもAWS IoT Device SDKを使うととてもシンプルに実装できます。 とりあえず色々なデバイスに実装してみるところから初めてみましょう。